package com.ys.web.pay.conrtoller;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.IdUtil;
import com.ys.base.BaseConstants;
import com.ys.base.EnumType;
import com.ys.utils.annotation.RiskValidation;
import com.ys.utils.annotation.UserGroupNumberCheck;
import com.ys.utils.annotation.UserWithdrawBlack;
import com.ys.utils.base.http.McodeHandler;
import com.ys.utils.base.http.ResponseHandler;
import com.ys.utils.base.j2se.*;
import com.ys.utils.help.GroupUtils;
import com.ys.utils.help.UserUtils;
import com.ys.utils.http.RSAUtils;
import com.ys.utils.pay.Result;
import com.ys.utils.redis.Redis;
import com.ys.utils.redis.key.GroupKey;
import com.ys.utils.spring.config.SystemError;
import com.ys.utils.spring.properties.Config;
import com.ys.web.pay.PayEnum;
import com.ys.web.pay.RedisKeyToYs;
import com.ys.web.pay.manager.PayManager;
import com.ys.web.pay.model.BusiTransferRecordCash;
import com.ys.web.pay.model.po.TransferConfirm;
import com.ys.web.pay.model.po.TransferCreate;
import com.ys.web.pay.service.TransferService;
import com.ys.web.user.friends.manager.FriendsManager;
import com.ys.web.user.friends.mapper.UserFriendsMapper;
import com.ys.web.user.friends.po.BaseGroupInfoPO;
import com.ys.web.user.friends.service.GroupService;
import com.ys.web.user.login.LoginInfo;
import com.ys.web.user.login.LoginService;
import com.ys.web.ws.bean.MessageResponseBean;
import com.ys.web.yinsheng.manager.YsWalletManager;
import com.ys.web.yinsheng.model.UserMerchant;
import com.ys.web.yinsheng.service.YinShengService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/webox/transfer/")
public class TransferController {
    @Autowired
    private UserFriendsMapper userFriendsMapper;
    @Autowired
    private LoginService loginService;
    @Autowired
    private TransferService transferService;
    @Autowired
    private YinShengService yinShengService;
    @Autowired
    private GroupService groupService;

    /**
     * 转账预下单
     *
     * @param uid
     * @param create
     * @return
     */

    @UserWithdrawBlack
    @RiskValidation
    @RequestMapping("create")
    public String create(@RequestAttribute Long uid,@RequestAttribute String ip, TransferCreate create) {
        if (Boolean.parseBoolean(Config.pp.get("trading.disable"))) {
            SystemError.wrapBs("500", "系统维护,交易系统已关闭");
        }
        if (!Boolean.parseBoolean(Config.pp.get("trading.disable.transfer"))) {
            SystemError.wrapBs("500", "转账已关闭");
        }
        if(create.payChannel<3){
            if(Logger.isOnline()) {
                if (Boolean.parseBoolean(Config.pp.get("trading.disable.ys"))) {
                    SystemError.wrapBs("500", "银行卡转账已关闭");
                }
            }
            //查询收红包人钱包信息 uid
            UserMerchant userMerchant = yinShengService.userMerchant(uid+"");
            //查询转账人钱包信息 uid
            if(StringHandler.isEmpty(userMerchant)){
                SystemError.wrapBs("601", "该用户还未进行银行卡实名认证");
            }
        }
        if(create.payChannel==3){
            if(Logger.isOnline()) {
                if (!Boolean.parseBoolean(Config.pp.get("trading.disable.transfer.zfb"))) {
                    SystemError.wrapBs("500", "支付宝转账已关闭");
                }
            }
        }
        if(create.payChannel==5){
            if(Logger.isOnline()) {
                if (!Boolean.parseBoolean(Config.pp.get("trading.disable.transfer.hjzf"))) {
                    SystemError.wrapBs("500", "银行卡转账已关闭");
                }
            }
        }
//        UserUtils.validateUserAccountStatus(StringHandler.getString(uid));
        //验证用户是否能发送红包
        if (create.getGp().equals("2")) {
            //群聊
            BaseGroupInfoPO baseGroupInfoPO = GroupUtils.getCacheGroupInfo(create.getReceivedId());
            if (baseGroupInfoPO.getIsFreeze()) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "当前群已被禁止使用");
            }
            String key = GroupKey.groupMembersKey(create.getReceivedId());
            Set<String> members = Redis.zSet.range(key, 0, -1);
            if (members == null || members.isEmpty()) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "当前群已解散");
            } else {
                if (!members.contains(String.valueOf(uid))) {
                    SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "您已在再该群");
                }
            }
        } else {
            //私聊
//            Logger.info("uid1:" + uid);
//            Logger.info("uid2:" + McodeHandler.from32Radix(create.getReceivedId()));
            int count = userFriendsMapper.isFriend(uid, String.valueOf(McodeHandler.from32Radix(create.getReceivedId())));
            if (count != 2) {
                SystemError.wrapBs("500", "开启了朋友验证，你还不是他(她)朋友，请先发送朋友验证请求，对方验证通过后，才能聊天。");
            }
            LoginInfo receivedId = loginService.infoByUid(StringHandler.getString(McodeHandler.from32Radix(create.getReceivedId())));
            if(receivedId.accountStatus!=0){
                SystemError.wrapBs("500", "好友信息不存在....");
            }
            //如果被拉入黑名单
            if (FriendsManager.isBlackFriend(String.valueOf(McodeHandler.from32Radix(create.getReceivedId())), uid) == 1) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "您与对方当前不是好友关系");
            }
        }
        // 数据验证
        create.check();
        LoginInfo userVo = loginService.infoByUid(StringHandler.getString(uid));

        if (create.getPayType()==3 && !PayManager.validatePayPassword(RSAUtils.decryptField(create.getPayPassword()), userVo)) {
            SystemError.wrapBs(EnumType.ResponseCode.ILLEGAL.getCode(), "密码错误");
        }
        //银盛发包金额限制
        if(create.getPayChannel()<3){
            YsWalletManager.checkUserLevel(Convert.objToStr(uid),Convert.objToStr(create.getAmount()), userVo.getRealIdCardUp(), yinShengService.getUserBankCount(uid));
        }
        if(create.getPayType()==4){
            try {
                Thread.sleep(500);
            } catch (InterruptedException ignored) {
            }
        }
        Result<Map<String, String>> returnResult = transferService.giveTransfer(create.getAmount(),
                create.getGp().equals("1") ? create.getReceivedId() : create.getReceivedIds(),
                StringHandler.getString(uid), create.getRemark(),
                create.getGp(), create.getGp().equals("2") ? create.getReceivedId() : null,
                StringHandler.getString(create.getPayType()),create.payChannel);
        if (returnResult.success()) {
            // 发送转账推送
            create.setReceivedIds(McodeHandler.to32Radix(StringHandler.getLong(create.getReceivedIds())));
            PayManager.send(uid, create, StringHandler.getString(returnResult.getResult().get("redId")));
        } else {
            SystemError.wrapBs(EnumType.ResponseCode.ILLEGAL.getCode(), returnResult.getMessage());
        }

        return ResponseHandler.success();
    }



    /**
     * 转账确认
     *
     * @param uid
     * @param transferConfirm
     * @return
     */
    @UserGroupNumberCheck
    @RiskValidation
    @RequestMapping("confirm")
    public String confirm(@RequestAttribute long uid,@RequestAttribute String ip, String messageId, TransferConfirm transferConfirm) {
        if (Boolean.parseBoolean(Config.pp.get("trading.disable"))) {
            SystemError.wrapBs("500", "系统维护,交易系统已关闭");
        }
        UserMerchant inUser = null;
        UserUtils.validateUserAccountStatus(StringHandler.getString(uid));
        Result<Map<String, String>> returnResult;
        Object object = Redis.str.get(RedisKeyToYs.REDIS_TRANSFER_PREFIX + transferConfirm.getSerialNumber());
        if (StringHandler.isEmpty(object)) {
            SystemError.wrapBs("400", "转账不存在或已过期");
        }
        BusiTransferRecordCash recordCash = transferService.getBusiTransferRecordCashById(Long.parseLong(transferConfirm.getSerialNumber()));
        if(recordCash.payChannel<3) {
            if (Boolean.parseBoolean(Config.pp.get("trading.disable.ys"))) {
                SystemError.wrapBs("500", "银行卡转账已关闭");
            }
            //查询收红包人钱包信息 uid
            inUser = yinShengService.userMerchant(uid + "");
            if(StringHandler.isEmpty(inUser)){
                SystemError.wrapBs("601", "该用户还未进行银行卡实名认证");
            }
        }
        if(recordCash.payChannel==5){
            if(Logger.isOnline()) {
                if (Boolean.parseBoolean(Config.pp.get("trading.disable.hjzf"))) {
                    SystemError.wrapBs("500", "银行卡转账已关闭");
                }
            }
        }
        //验证用户是否能抢红包
        if (recordCash.getType() != StringHandler.getInt(PayEnum.RedPackageType.Single.getCode())) {
            //群聊
            BaseGroupInfoPO baseGroupInfoPO = GroupUtils.getCacheGroupInfo(recordCash.getGroupName());
            if (baseGroupInfoPO.getIsFreeze()) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "当前群已被禁止使用");
            }
            String key = GroupKey.groupMembersKey(recordCash.getGroupName());
            Set<String> members = Redis.zSet.range(key, 0, -1);
            if (members == null || members.isEmpty()) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "当前群已解散");
            } else {
                if (!members.contains(String.valueOf(uid))) {
                    SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "您已在再该群");
                }
            }
            if(!recordCash.getListUserId().equals(String.valueOf(uid))) {
                if (!GroupUtils.isManager(uid, recordCash.getGroupName())) {
                    SystemError.wrapBs("400", "不能领取别人的转账");
                }
            }
        } else {
            //私聊
            //私聊
//            Logger.info("uid1:" + uid);
//            Logger.info("uid2:" + recordCash.getUserId());
            int count = userFriendsMapper.isFriend(uid, String.valueOf(recordCash.getUserId()));
            if (count != 2) {
                SystemError.wrapBs("500", "开启了朋友验证，你还不是他(她)朋友，请先发送朋友验证请求，对方验证通过后，才能聊天。");
            }
            if(FriendsManager.isBlackFriend(StringHandler.getString(recordCash.getUserId()), uid) == 1){
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "你已被对方拉黑");
            }
        }

        String key = RedisKeyToYs.REDIS_TRANSFER_SINGLE_PREFIX + transferConfirm.getSerialNumber() + "-" + recordCash.listUserId;
        if (!Redis.key.exists(key)) {
            SystemError.wrapBs("400", "转账已领取");
        }
        // 抢红包 加锁
        returnResult = transferService.getTransferPackage(transferConfirm.getSerialNumber(), recordCash, StringHandler.getString(uid),inUser);//自己抢自己的红包不推送
        if (returnResult.success()) {
            ThreadUtil.execAsync(() -> {
                String toId = McodeHandler.to32Radix(uid);
                LoginInfo cacheUser = UserUtils.getCacheUser(recordCash.getUserId());
                LoginInfo cacheUser2 = UserUtils.getCacheUser(uid);
                MessageResponseBean messageResponseBean = PayManager.getMessageResponseBean(
                        IdUtil.randomUUID().toUpperCase(), toId, BaseConstants.SINGLE_PREFIX + toId, cacheUser2.getAvatarUrl(), cacheUser.getNickName(),
                        JsonUtil.toJson(MapHandler.initMap("status", "转账完成"
                                , "amount", StringHandler.fenToYuan(StringHandler.getString(recordCash.getAmount()))
                                , "messageId", messageId)),
                        DateUtil.getDate(new Date(), BaseConstants.BASE_FORMAT),
                        EnumType.MessageCode.MESSAGE_TRANSFER_CONFIRM.getCode(), 0.0, 0.0,null,recordCash.payChannel
                );
                if (recordCash.getType() == 1) {
                    GroupUtils.sendIfAbsent(messageResponseBean, String.valueOf(recordCash.getUserId()), BaseConstants.SINGLE_PREFIX + toId);
                } else {
                    messageResponseBean.setGroupId(recordCash.getGroupName());
                    messageResponseBean.setGroupPic(GroupUtils.getCacheGroupInfo(recordCash.getGroupName()).getPic());
                    messageResponseBean.setGroupName(UserUtils.getGroupCacheNameByGroupId(recordCash.getGroupName()));
                    GroupUtils.sendIfAbsent(messageResponseBean, String.valueOf(recordCash.getUserId()), BaseConstants.GROUP_PREFIX + recordCash.getGroupName());
                }
            });
        }
        return returnResult.success() ? ResponseHandler.success() : ResponseHandler.error("400", returnResult.getMessage());
    }

    /**
     * 转账拒收
     *
     * @param uid
     * @param transferConfirm
     * @return
     */
    @RequestMapping("refuse")
    public String refuse(@RequestAttribute long uid,@RequestAttribute String ip, String messageId, TransferConfirm transferConfirm) {
        if (Boolean.parseBoolean(Config.pp.get("trading.disable"))) {
            return ResponseHandler.error("500", "交易系统已关闭");
        }
        Object object = Redis.str.get(RedisKeyToYs.REDIS_TRANSFER_PREFIX + transferConfirm.getSerialNumber());
        if (StringHandler.isEmpty(object)) {
            SystemError.wrapBs("400", "转账不存在或已过期");
        }
        BusiTransferRecordCash recordCash = transferService.getBusiTransferRecordCashById(Long.parseLong(transferConfirm.getSerialNumber()));
        if (recordCash.getType() != StringHandler.getInt(PayEnum.RedPackageType.Single.getCode())) {
            //群聊
            BaseGroupInfoPO baseGroupInfoPO = GroupUtils.getCacheGroupInfo(recordCash.getGroupName());
            if (baseGroupInfoPO.getIsFreeze()) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "当前群已被禁止使用");
            }
            String key = GroupKey.groupMembersKey(recordCash.getGroupName());
            Set<String> members = Redis.zSet.range(key, 0, -1);
            if (members == null || members.isEmpty()) {
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "当前群已解散");
            } else {
                if (!members.contains(String.valueOf(uid))) {
                    SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "您已在再该群");
                }
            }
        } else {
            //私聊
//            Logger.info("uid1:" + uid);
//            Logger.info("uid2:" + recordCash.getUserId());
            int count = userFriendsMapper.isFriend(uid, String.valueOf(recordCash.getUserId()));
            if (count != 2) {
                SystemError.wrapBs("500", "开启了朋友验证，你还不是他(她)朋友，请先发送朋友验证请求，对方验证通过后，才能聊天。");
            }
            if(FriendsManager.isBlackFriend(StringHandler.getString(recordCash.getUserId()), uid) == 1){
                SystemError.wrapBs(EnumType.ResponseCode.Fail.getCode(), "你已被对方拉黑");
            }
        }

        if (recordCash.getStatus() != 1 || !recordCash.getListUserId().equals(String.valueOf(uid))) {
            SystemError.wrapBs("400", "退还失败！");
        }

        // 修改转账状态
        recordCash.setStatus(Integer.parseInt(PayEnum.RedPackageStatus.Expire.getCode()));
        Result<BusiTransferRecordCash> redRecordResult = transferService.refuseBusiTransferRecord(recordCash);
        if (!redRecordResult.success()) {
            SystemError.wrapBs("400", "退还失败");
        }
        ThreadUtil.execAsync(() -> {
            String toId = McodeHandler.to32Radix(uid);
            LoginInfo cacheUser = UserUtils.getCacheUser(recordCash.getUserId());
            LoginInfo cacheUser2 = UserUtils.getCacheUser(uid);
            MessageResponseBean messageResponseBean = PayManager.getMessageResponseBean(
                    IdUtil.randomUUID().toUpperCase(), toId, BaseConstants.SINGLE_PREFIX + toId, cacheUser2.getAvatarUrl(), cacheUser.getNickName(),
                    JsonUtil.toJson(MapHandler.initMap("status", "已退回"
                            , "amount", StringHandler.fenToYuan(StringHandler.getString(recordCash.getAmount()))
                            , "serialNumber", transferConfirm.getSerialNumber()
                            , "messageId", messageId)),
                    DateUtil.getDate(new Date(), BaseConstants.BASE_FORMAT),
                    EnumType.MessageCode.MESSAGE_TRANSFER_REFUSE.getCode(), 0.0, 0.0,null,recordCash.payChannel
            );
            if (recordCash.getType() == 1) {
                GroupUtils.sendIfAbsent(messageResponseBean, String.valueOf(recordCash.getUserId()), BaseConstants.SINGLE_PREFIX + toId);
            } else {
                messageResponseBean.setGroupId(recordCash.getGroupName());
                messageResponseBean.setGroupPic(GroupUtils.getCacheGroupInfo(recordCash.getGroupName()).getPic());
                messageResponseBean.setGroupName(UserUtils.getGroupCacheNameByGroupId(recordCash.getGroupName()));
                GroupUtils.sendIfAbsent(messageResponseBean, String.valueOf(recordCash.getUserId()), BaseConstants.GROUP_PREFIX + recordCash.getGroupName());
            }
        });

        return ResponseHandler.success();
    }

    /**
     * 转账查询接口
     *
     * @param transferConfirm
     * @return
     */
    @RequestMapping("query")
    public String grabHistory(@RequestAttribute long uid, TransferConfirm transferConfirm) {
        BusiTransferRecordCash recordCash = transferService.getBusiTransferRecordCashById(Long.parseLong(transferConfirm.getSerialNumber()));
        if (StringHandler.isEmpty(recordCash)) {
            SystemError.wrapBs("400", "转账不存在");
        }
        Integer status = recordCash.getStatus();// 状态
        String confirm = "1";
        // 自己发出的转账 ，自己不能领取
        if (recordCash.getUserId()==uid || status != 1 || !recordCash.getListUserId().equals(String.valueOf(uid))) {
            confirm = "2";
        }
        if(recordCash.gp==2){
            if(!recordCash.getListUserId().equals(String.valueOf(uid))) {
                if (!GroupUtils.isManager(uid, recordCash.getGroupName())) {
                    confirm = "2";
                }else{
                    confirm = "1";
                }
            }
        }
        return ResponseHandler.success(MapHandler.initMap("amount", StringHandler.fenToYuan(StringHandler.getString(recordCash.getAmount()))
                , "createDateTime", DateUtil.getDate(recordCash.getRawAddTime(), "yyy-MM-dd HH:mm:ss")
                , "completeDateTime", status > 1 ? DateUtil.getDate(recordCash.getRawUpdateTime(), "yyy-MM-dd HH:mm:ss") : ""
                , "confirm", confirm
                , "status", PayEnum.RedPackageStatus.getDescByCode(StringHandler.getString(status))
                , "statusValue", StringHandler.getString(status)
        ));
    }
}
